package com.czm.test;

import java.util.*;

/**
 * @author CZM
 * @date 2022 06 18 12:07
 */
public class Day08 {
    public static void main(String[] args) {
//        test075();
//        test074();
//        test074_2();
        char a = 'a';
        char b = 'b';
        char c = 'c';
        char A = 'A';
        char B = 'B';
        Character aa = 'a';
        Character bb = 'b';
        Character zz = 'z';

        Character AA = 'A';
        Character BB = 'B';
//        System.out.println(a > b);
//        System.out.println(a > c);
//        System.out.println(A > B);
//        System.out.println(a > B);
//        System.out.println(aa.compareTo(BB));
//        System.out.println(aa.compareTo(zz));

//        test073();

        // String[] split = (123 + "").split("");
        // for (String s :split) {
        //     System.out.println(s);
        // }
        // System.out.println(split.length);

        test070();
        // test70_2();
    }

    /**
     * 输入一串字符串
     * 字符串长度不超过100
     * 查找字符串中相同字符连续出现的最大次数
     * <p>
     * 输入描述
     * 输入只有一行，包含一个长度不超过100的字符串
     * <p>
     * 输出描述
     * 输出只有一行，输出相同字符串连续出现的最大次数
     * <p>
     * 说明：
     * 输出
     * <p>
     * 示例1：
     * 输入
     * hello
     * 输出
     * 2
     * <p>
     * 示例2：
     * 输入
     * word
     * 输出
     * 1
     * <p>
     * 示例3：
     * 输入
     * aaabbc
     * 输出
     * 3
     * <p>
     * 字符串区分大小写
     */
    // 字符串连续出现最大次数
    public static void test075() {
        Scanner sc = new Scanner(System.in);
        String line = sc.nextLine();
        String[] split = line.split("");
        // 出现次数，初始值为1
        int sum = 1;
        // 最大次数
        int res = 0;
        for (int i = 0; i < split.length; i++) {
            // 连续相同字符串
            while (i + 1 < split.length && split[i].equals(split[i + 1])) {
                sum++;
                i++;
            }
            // 比较出最大的
            res = Math.max(res, sum);
            // 初始化出现次数
            sum = 1;
        }
        System.out.println(res);
    }

    public static void test075_2() {
        Scanner in = new Scanner(System.in);
        String str = in.nextLine();
        in.close();

        char[] chars = str.toCharArray();

        int maxLen = 0;

        for (int i = 0; i < chars.length; i++) {
            int index = i;
            int len = 1;
            while (index + 1 < chars.length && chars[index + 1] == chars[index]) {
                len++;
                index++;
            }
            if (len > maxLen) maxLen = len;
        }

        System.out.println(maxLen);

    }

    /**
     * 特定大小的停车场 数组cars表示
     * 其中1表示有车  0表示没车
     * 车辆大小不一，小车占一个车位(长度1)
     * 货车占两个车位(长度2)
     * 卡车占三个车位(长度3)
     * 统计停车场最少可以停多少辆车
     * 返回具体的数目
     * <p>
     * 输入描述：
     * 整型字符串数组cars
     * 其中1表示有车0表示没车
     * 数组长度<1000
     * <p>
     * 输出描述：
     * 整型数字字符串
     * 表示最少停车数
     * <p>
     * 示例1：
     * 输入
     * 1,0,1
     * 输出
     * 2
     * 说明：
     * 一个小车占第一个车位
     * 第二个车位空，一个小车占第三个车位
     * 最少有两辆车
     * <p>
     * 示例2:
     * 输入：
     * 1,1,0,0,1,1,1,0,1
     * 输出：
     * 3
     * 说明：
     * 一个货车占第1,2个车位
     * 第3,4个车位空
     * 一个卡车占第5,6,7个车位
     * 第8个车位空
     * 一个小车占第9个车位
     * 最少3俩个车
     */
    // 最少停车数
    public static void test074() {
        Scanner sc = new Scanner(System.in);
        String line = sc.nextLine();
        String[] split = line.split(",");
        // 连续1的次数
        int count = 0;
        // 找出所有的连续1的次数，存在list中
        List<Integer> list = new ArrayList<>();
        for (int i = 0; i < split.length; i++) {
            // 找出连续1的次数
            while (i < split.length && "1".equals(split[i])) {
                count++;
                i++;
            }
            // 连续1的次数大于0，存入list中
            if (count != 0) {
                list.add(count);
            }
            // 初始化
            count = 0;
        }
        int res = 0;
        for (int i = 0; i < list.size(); i++) {
            // 累加结果，算出能停几辆卡车
            res += list.get(i) / 3;
            // 如果%3有剩余的，则再加一辆，不用管余1还是余2，最小都是一辆
            if (list.get(i) % 3 != 0) {
                res++;
            }
        }
        System.out.println(res);
    }

    public static void test074_2() {
        Scanner in = new Scanner(System.in);
        String cars = in.nextLine()
                .replaceAll(",", "");
        in.close();

        int count = 0;

        // 正则表达式，根据一个或多个0进行切割
        String[] split = cars.split("[0]+");
        for (String car : split) {
            int len = car.length();
            while (len > 3) {
                count++;
                len -= 3;
            }
            if (len != 0) {
                count++;
            }
        }

        System.out.println(count);
    }

    /**
     * 给出一个只包含字母的字符串,
     * 不包含空格,统计字符串中各个子字母(区分大小写)出现的次数,
     * 并按照字母出现次数从大到小的顺序输出各个字母及其出现次数
     * 如果次数相同,按照自然顺序排序,且小写字母在大写字母之前
     * <p>
     * 输入描述:
     * 输入一行仅包含字母的字符串
     * <p>
     * 输出描述:
     * 按照字母出现次数从大到小的顺序输出各个字母和字母次数,
     * 用英文分号分割,
     * 注意末尾的分号
     * 字母和次数中间用英文冒号分隔
     * <p>
     * 示例:
     * 输入: xyxyXX
     * 输出:x:2;y:2;X:2;
     * 说明:每个字符出现的次数为2 故x排在y之前
     * 而小写字母x在大写X之前
     * <p>
     * 示例2:
     * 输入:
     * abababb
     * 输出:
     * b:4;a:3
     * 说明:b的出现个数比a多 故排在a前
     */
    // PS：这道题按我的理解我做的是对的，先按次数排序，排完在按a~z A~Z排序。但是案例给的不清楚，或许可以 a~z中按次数排序，后在A~Z中按次数排序，就是小写在前，大写在后
    // 字母多条件排序
    public static void test073() {
        Scanner sc = new Scanner(System.in);
        char[] chars = sc.nextLine().toCharArray();
        // 用一个map，key存字符，value存字符出现次数
        Map<Character, Integer> map = new HashMap<>();
        for (int i = 0; i < chars.length; i++) {
            char c = chars[i];
            if (map.containsKey(c)) {
                map.put(c, map.get(c) + 1);
            } else {
                map.put(c, 1);
            }
        }
        // 小写字符的ACSII码大于大写字符， a~z 递增  A~Z递增
        Set<Map.Entry<Character, Integer>> entries = map.entrySet();
        // 排序  排序规则：当返回的数字大于0，则进行换位置，否则不换
        entries.stream().sorted((s1, s2) -> {
            // 按次数排序
            if (s1.getValue() - s2.getValue() != 0) {
                return s2.getValue() - s1.getValue();
            }
            Character key1 = s1.getKey();
            Character key2 = s2.getKey();
            // a~z 两个小写字母之间的比较
            if (key1.compareTo('A') > 25 && key2.compareTo('A') > 25) {
                return key1 - key2;  // 字符a~z  A~Z之间加减返回数字
            }
            // A~Z 两个大写字母之间的比较
            if (key1.compareTo('A') < 26 && key2.compareTo('A') < 26) {
                return key1 - key2;
            }
            // a~z 混 A~Z  大小写字母之间的比较，大写在后
            return -(key1 - key2);
        }).forEach((s) -> {
            System.out.print(s.getKey() + ":" + s.getValue() + ";");
        });
    }


    /**
     *
     */
    public static void test072() {

    }

    /**
     * 现在有一队小朋友，他们高矮不同，
     * 我们以正整数数组表示这一队小朋友的身高，如数组{5,3,1,2,3}。
     * 我们现在希望小朋友排队，以“高”“矮”“高”“矮”顺序排列，
     * 每一个“高”位置的小朋友要比相邻的位置高或者相等；
     * 每一个“矮”位置的小朋友要比相邻的位置矮或者相等；
     * 要求小朋友们移动的距离和最小，第一个从“高”位开始排，输出最小移动距离即可。
     * 例如，在示范小队{5,3,1,2,3}中，{5, 1, 3, 2, 3}是排序结果。
     * {5, 2, 3, 1, 3} 虽然也满足“高”“矮”“高”“矮”顺序排列，
     * 但小朋友们的移动距离大，所以不是最优结果。
     * 移动距离的定义如下所示：
     * 第二位小朋友移到第三位小朋友后面，移动距离为1，
     * 若移动到第四位小朋友后面，移动距离为2；
     * <p>
     * 输入描述:
     * 排序前的小朋友，以英文空格的正整数：
     * 4 3 5 7 8
     * 注：小朋友<100个
     * 输出描述:
     * 排序后的小朋友，以英文空格分割的正整数：
     * 4 3 7 5 8
     * 备注：4（高）3（矮）7（高）5（矮）8（高），
     * 输出结果为最小移动距离，只有5和7交换了位置，移动距离都是1.
     * <p>
     * 示例一：
     * 输入
     * 4 1 3 5 2
     * 输出
     * 4 1 5 2 3
     * <p>
     * 示例二：
     * 输入
     * 1 1 1 1 1
     * 输出
     * 1 1 1 1 1
     * 说明：相邻位置可以相等
     * <p>
     * 示例三：
     * 输入：
     * xxx
     * 输出
     * []
     * 说明：出现非法参数情况，返回空数组
     */
    // PS:对案例
    //      输入
    //       4 1 3 5 2
    //     输出
    //       4 1 5 2 3
    // 有疑问，最有不应该是 4 1 3 2 5 吗？？？ 代码是照着案例写的，我认为通过率没有100%，没有测试数据，网上好多答案也是这样子写的，懵了
    public static void test071() {
        Scanner sc = new Scanner(System.in);
        String line = sc.nextLine();
        List<Integer> list = new ArrayList<>();
        try {
            String[] split = line.split(" ");
            for (int i = 0; i < split.length; i++) {
                list.add(Integer.parseInt(split[i]));
            }
        }catch (Exception e){
            // 输入异常情况
            System.out.println("[]");
            return;
        }
        // 用于判断当前是高矮 还是 矮高
        boolean flag = true;
        for (int i = 0; i + 1 < list.size(); i++) {
            if (flag) {
                // 高 矮
                if (list.get(i) < list.get(i + 1)) {
                    // 是矮 高，则交换位置
                    int temp = list.get(i);
                    list.set(i, list.get(i + 1));
                    list.set(i + 1, temp);
                }
                // 判断完高 矮，切换为 矮 高
                flag = false;
            } else {
                // 矮 高
                if (list.get(i) > list.get(i + 1)) {
                    // 是高 矮，则交换位置
                    int temp = list.get(i);
                    list.set(i, list.get(i + 1));
                    list.set(i + 1, temp);
                }
                // 判断完矮 高，切换为高 矮
                flag = true;
            }
        }
        for (int i = 0; i < list.size(); i++) {
            System.out.print(list.get(i) + " ");
        }
    }

    /**
     *所谓的水仙花数是指一个n位的正整数其各位数字的n次方的和等于该数本身，
     例如153=1^3+5^3+3^3,153是一个三位数
     输入描述
     第一行输入一个整数N，
     表示N位的正整数N在3-7之间包含3,7
     第二行输入一个正整数M，
     表示需要返回第M个水仙花数
     输出描述
     返回长度是N的第M个水仙花数，
     个数从0开始编号，
     若M大于水仙花数的个数返回最后一个水仙花数和M的乘积，
     若输入不合法返回-1

     示例一：

     输入
     3
     0
     输出
     153
     说明：153是第一个水仙花数
     示例二：
     输入
     9
     1
     输出
     -1
     */
    // 水仙花数
    public static void test070() {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int m = sc.nextInt();
        if (n < 3 || n > 7) {
            System.out.println(-1);
            return;
        }
        // 起始数
        int start = (int) Math.pow(10, n - 1);
        // 终止数
        int end = (int) Math.pow(10, n);
        List<Integer> reslist = new ArrayList<>();
        for (int i = start; i < end; i++) {
            int sum = 0;
            // 求每位数的简单解法
            // String[] split = (i + "").split("");
            // for (String s : split) {
            //     sum += Math.pow(Integer.parseInt(s), n);
            // }
            // 算出每位数
            List<Integer> list1 = singleNum(i);
            for (Integer s : list1) {
                // 每位数进行n次方并累加
                sum += Math.pow(s, n);
            }
            // 满足要求的放进结果集中
            if (sum == i) {
                reslist.add(i);
            }
        }
        if (m >= reslist.size()) {
            System.out.println(reslist.get(reslist.size() - 1) * m);
        } else {
            System.out.println(reslist.get(m));
        }
    }

    /**
     * 将一个整型数从后往前输出单个数字
     * @param num
     * @return
     */
    public static List<Integer> singleNum(int num){
        List<Integer> list = new ArrayList<>();
        while (num > 0) {
            int singleNum  = num % 10;
            list.add(singleNum);
            num = num /10;
        }
        return list;
    }

    public static void test70_2(){
        Scanner in = new Scanner(System.in);

        int N = Integer.parseInt(in.nextLine());
        int M = Integer.parseInt(in.nextLine());
        in.close();

        if (N < 3 || N > 7) {
            System.out.println(-1);
            return;
        }

        LinkedList<Integer> res = new LinkedList<>();

        int start = (int) Math.pow(10, N - 1);
        int end = (int) Math.pow(10, N);

        for (int i = start; i < end; i++) {
            int sum = 0;
            int bit = start;
            while (bit != 1) {
                sum += Math.pow(i / bit % 10, N);
                bit /= 10;
            }
            sum += Math.pow(i % 10, N);
            if (sum == i) {
                res.add(i);
            }
            if (res.size() == M + 1) {
                System.out.println(i);
                return;
            }
        }

        if (M > res.size()) {
            System.out.println(M * res.getLast());
        }
    }


    /**
     * 游戏规则：输入一个只包含英文字母的字符串，
     字符串中的俩个字母如果相邻且相同，就可以消除。
     在字符串上反复执行消除的动作，
     直到无法继续消除为止，
     此时游戏结束。
     输出最终得到的字符串长度。

     输出：原始字符串str只能包含大小写英文字母，字母的大小写敏感，长度不超过100，
     输出游戏结束后字符串的长度

     备注：输入中包含非大小写英文字母是均为异常输入，直接返回0。

     事例：mMbccbc输出为3
     */
    public static void test069() {

    }
}
